package org.bing.engine.controller;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;

import org.bing.engine.common.logging.Log;
import org.bing.engine.common.logging.LogFactory;
import org.bing.engine.common.remoting.hessian.HessianServlet;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    private static Log logger = LogFactory.getLog(Main.class);

    private static void clean(Server server) {
        try {
            server.stop();
        } catch (Exception e) {
            logger.error("Fail to stop jetty!", e);
            server.destroy();
        }
    }

    private static void sleep(long time) {
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            // ignore
        }
    }

    @SuppressWarnings("serial")
    private static void start(Server server, final ApplicationContext appContext) {
        try {
            ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
            context.setContextPath("/controller");
            context.addServlet(new ServletHolder(new HessianServlet() {
                @Override
                public void init(ServletConfig config) throws ServletException {
                    context = appContext;
                    super.init(config);
                }
            }), "/hessian/*");
            server.setHandler(context);
            server.start();
        } catch (Throwable t) {
            logger.error("Fail to run controller!", t);
            clean(server);
            sleep(3000);
        }
    }

    public static void main(String[] args) throws Exception {
        Thread.currentThread().setName("bing-controller-main");
        List<String> loc = new ArrayList<String>();
        loc.add("classpath*:/META-INF/bing-controller-spring-*.xml");
        loc.add("classpath*:/META-INF/bing-container-*-spring.xml");
        loc.add("classpath*:/META-INF/bing-health-spring-*.xml");
        ApplicationContext context = new ClassPathXmlApplicationContext(loc.toArray(new String[loc.size()]));
        org.eclipse.jetty.util.log.Log.setLog(new org.bing.logging.JettySlf4jLogger());
        Server server = (Server) context.getBean("controller.JettyServer");
        while (true) {
            // TODO impl controller upgrade, health check etc
            if (server.isStarting() || server.isStarted()) {
                sleep(5000);
            } else {
                start(server, context);
            }
        }
    }

}
